package com.example.airhockey1

import android.content.Context
import android.opengl.GLES20
import android.opengl.GLES20.*
import android.opengl.GLSurfaceView
import android.util.Log
import com.example.airhockey1.helper.ShaderHelper
import com.example.airhockey1.utils.OpenGLUtils
import java.nio.ByteBuffer
import java.nio.ByteOrder
import java.nio.FloatBuffer
import javax.microedition.khronos.egl.EGLConfig
import javax.microedition.khronos.opengles.GL10

/**
 *  @author : BuildF
 *  date : 2020/7/9 15:56
 *  description :
 */
class AirHockeyRenderer constructor(context: Context) :
    GLSurfaceView.Renderer {
    private val U_COLOR = "u_Color"
    private val A_POSITION = "a_Position"
    private val POSITION_COMPONENT_COUNT = 2
    private val BYTES_PER_FLOAT = 4
    private var vertexData: FloatBuffer? = null
    private val context: Context by lazy { context }
    private var program = 0
    private var uColorLocation = 0
    private var aPositionLocation = 0


    init {
        var tableVertices: FloatArray = floatArrayOf(0f, 0f, 0f, 14f, 9f, 14f, 9f, 0f)
        val tableVerticesWithTriangles: FloatArray = floatArrayOf(
            -0.5f, -0.5f,
            0.5f, 0.5f,
            -0.5f, 0.5f,

            -0.5f, -0.5f,
            0.5f, -0.5f,
            0.5f, 0.5f,

            //line1
            -0.5f, 0f,
            0.5f, 0f,

            //mallets
            0f, -0.25f,
            0f, 0.25f

        )
        vertexData =
                //分配一块本地内存，这块内存不会被垃圾回收器管理，
            ByteBuffer.allocateDirect(tableVerticesWithTriangles.size * BYTES_PER_FLOAT)
                //按照本地字节序排列
                .order(ByteOrder.nativeOrder())
                //转回成浮点型实例
                .asFloatBuffer()

        //将数据从内存复制到刚分配的本地内存
        vertexData?.put(tableVerticesWithTriangles)
    }

    override fun onDrawFrame(p0: GL10?) {
        Log.d("ljy", "onDrawFrame")
        glClear(GL_COLOR_BUFFER_BIT)
        //uniform 的分量没有默认值，因为是vec4类型，需要提供4个分量的值 因为想要以一张白桌子为开始，因此将4个值设置为全亮度的1.0f
        glUniform4f(uColorLocation, 1.0f, 1.0f, 1.0f, 1.0f)
        /* 指定了参数后 就可以绘制桌子了 第一个参数代表要绘制的图形 现在是绘制三角形，
          第二个参数表示要从开头处读顶点，第三个参数代表要读几个顶点
          我们要绘画一个长方形 所以是6个顶点 两个三角形*/
        glDrawArrays(GLES20.GL_TRIANGLES, 0, 6)

        //绘制分割线
        glUniform4f(uColorLocation, 0.0f, 0.0f, 0.0f, 1.0f)
        glDrawArrays(GL_LINES, 6, 2)

        //画两个木槌
        glUniform4f(uColorLocation, 0.0f, 0.0f, 0.0f, 1.0f)
        glDrawArrays(GL_POINTS, 8, 1)

        glUniform4f(uColorLocation, 0.0f, 0.0f, 0.0f, 1.0f)
        glDrawArrays(GL_POINTS, 9, 1)


    }

    override fun onSurfaceChanged(p0: GL10?, width: Int, height: Int) {
        Log.d("ljy", "onSurfaceChanged")
        glViewport(0, 0, width, height)
    }


    override fun onSurfaceCreated(p0: GL10?, p1: EGLConfig?) {
        Log.d("ljy", "onSurfaceCreated")
        glClearColor(0.0f, 0.0f, 0.0f, 0.0f)
        val vertexShaderSource =
            OpenGLUtils.getShaderFromAssets(
                context, "simple_vertex_shader.glsl"
            )
        val fragmentShaderSource =
            OpenGLUtils.getShaderFromAssets(
                context, "simple_fragment_shader.glsl"
            )
        val vertexShader = ShaderHelper.compileVertexShader(vertexShaderSource)
        val fragmentShader =
            ShaderHelper.compileFragmentShader(fragmentShaderSource)
        program = ShaderHelper.linkProgram(vertexShader, fragmentShader)
        if (BuildConfig.DEBUG) {
            ShaderHelper.validateProgram(program)
        }
        //在绘制任何东西到屏幕上面都要使用这里定义的程序
        glUseProgram(program)

        //获取uniform的位置 并将这个位置存入uColorLocation
        uColorLocation = glGetUniformLocation(program, U_COLOR)

        //获取属性的位置
        aPositionLocation = glGetAttribLocation(program, A_POSITION)

        //设置初始读取位置为0
        vertexData?.position(0)
        //告诉OpenGL 可以在缓冲区vertexData中找到a_position对应的数据
        glVertexAttribPointer(
            aPositionLocation,
            POSITION_COMPONENT_COUNT,
            GL_FLOAT,
            false,
            0,
            vertexData
        )
        glEnableVertexAttribArray(aPositionLocation)
    }
}